package cn.bqjr.eily.shiro.spring.boot;

import cn.bqjr.eily.utils.I18nUtils;
import org.apache.shiro.authc.ExcessiveAttemptsException;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * 登录错误重试 抽象管理
 */
public abstract class AbstractLoginRetryMgr implements ILoginRetryManager {
    private LoginRetryCache loginRetryCache;
    private Boolean enabledLoginRetryLimit;
    private Integer loginRetryLimitCount;
    private Long loginRetryLimitTime;
    private Long loginRetryLockTime;

    public AbstractLoginRetryMgr() {
    }

    public void setLoginRetryCache(LoginRetryCache loginRetryCache) {
        this.loginRetryCache = loginRetryCache;
    }

    public void setEnabledLoginRetryLimit(Boolean enabledLoginRetryLimit) {
        this.enabledLoginRetryLimit = enabledLoginRetryLimit;
    }

    public void setLoginRetryLimitCount(Integer loginRetryLimitCount) {
        this.loginRetryLimitCount = loginRetryLimitCount;
    }

    public void setLoginRetryLimitTime(Long loginRetryLimitTime) {
        this.loginRetryLimitTime = loginRetryLimitTime;
    }

    public void setLoginRetryLockTime(Long loginRetryLockTime) {
        this.loginRetryLockTime = loginRetryLockTime;
    }

    @Override
    public Integer increase(String loginId) {
        if (enabledLoginRetryLimit) {
            AtomicInteger original = loginRetryCache.getRetryCount(loginId);
            int newCount = original.incrementAndGet();
            if (newCount >= loginRetryLimitCount) {
                loginRetryCache.updateRetryCount(loginId, original, loginRetryLockTime);
                throw new ExcessiveAttemptsException(I18nUtils.getMsg("error.login.excessiveAttempts"));
            } else if (newCount == 1) {
                loginRetryCache.updateRetryCount(loginId, original, loginRetryLimitTime);
            } else {
                loginRetryCache.updateRetryCount(loginId, original);
            }
            return (loginRetryLimitCount - newCount);
        }
        return null;
    }

    @Override
    public void validate(String loginId) {
        if (enabledLoginRetryLimit) {
            int count = loginRetryCache.getRetryCount(loginId).intValue();
            if (count >= loginRetryLimitCount) {
                throw new ExcessiveAttemptsException(I18nUtils.getMsg("error.login.excessiveAttempts"));
            }
        }
    }

    @Override
    public void unLock(String loginId) {
        if (enabledLoginRetryLimit) {
            loginRetryCache.delete(loginId);
        }
    }
}
